//-----------------------------------------------------------------------------
// Filename: ForgottenPasswordController.cs
//
// Description: A controller class that emails forgotten passwords.
//
// History:
// 18 Dec 2004	Aaron Clauson	Created.
//
// License: 
// Public Domain.
//-----------------------------------------------------------------------------

using System;
using System.Collections;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml;
using MaverickLite.Aza.Model;
using MaverickLite.Config;
using MaverickLite.Controller;
using log4net;

namespace MaverickLite.Security
{
	/// <summary>
	/// Controller that sends email notifications of forgotten passwords.
	/// </summary>
	public class ForgottenPasswordController : SecureXmlController
	{
		public const string REQUEST_USERNAMEOREMAILADDRESS_KEY = "usernameoremailaddress";	// Request form field containing the username or email address to send the forgotten password for.
		public const string REQUEST_FORMSUBMITTED_KEY = "formsubmitted";					// Name of the hiden field on the forgotten password page that indicates the form has been submitted.

		public ForgottenPasswordController(XmlElement initParams) : base(initParams)
		{}

		public override void BuildPageModel()
		{
			logger.Debug("ForgottenPasswordController InitialiseRequest.");
		
			Hashtable formData = MavRequestState.GetRequestData();

			string account = formData[REQUEST_USERNAMEOREMAILADDRESS_KEY] as string;
			string submitted = formData[REQUEST_FORMSUBMITTED_KEY] as string;

			logger.Debug("Account = " + account + ", submitted = " + submitted + ".");

			string emailaddress = null;
			string password = null;
			string username = null;

			try
			{
				GetPassword(account, out emailaddress, out username, out password);
			}
			catch(Exception getPwdExcp)
			{
				logger.Error("Exception calling GetPassword: " + getPwdExcp.Message);
				AddErrorMessage("Error attempting to retrieve account details. " + getPwdExcp.Message);
			}

			if(emailaddress != null && emailaddress.Trim().Length > 0 && username != null && username.Trim().Length > 0)
			{
				System.Web.Mail.MailMessage Message = new System.Web.Mail.MailMessage();
				Message.To = emailaddress;
				Message.From = "support@blueface.ie";
				Message.Subject = "Blue Face Account";
				Message.Body = "Your Blue Face account details are:\r\nUsername: " + username + "\r\nPassword: " + password + "\r\n\r\n";
				Message.Body += "If you would like further assistance please email Blue Face support at support@blueface.ie\r\n\r\n";
				Message.Body += "Thank you for using Blue Face.";

				try
				{
					System.Web.Mail.SmtpMail.Send(Message);
					logger.Debug("Confirmation/cancellation email sent to " + emailaddress + ".");

					string confirmation = "<page><username>" + username + "</username><emailaddress>" + emailaddress + "</emailaddress></page>";
					this.m_pageModel.AddToModel(confirmation, true);

					this.m_view = "emailsent";
				}
				catch(System.Web.HttpException ehttp)
				{
					logger.Warn("Exception attempting to send confirmation/cancellation email. " + ehttp.Message);
					this.AddErrorMessage("Error trying to send forgotten password email: " + ehttp.Message);
				}
			}
			else if(account != null && account.Trim().Length > 0 && submitted != null && submitted.Trim().Length > 0)
			{
				string accountEntered = "<page><account>" + account + "</account></page>";
				this.m_pageModel.AddToModel(accountEntered, true);

				this.AddErrorMessage("The username or email address does not belong to a valid account.");
			}
			else if(submitted != null && submitted.Trim().Length > 0)
			{
				this.AddErrorMessage("Please specify either your username or email address.");
			}
		}

		/// <summary>
		/// Retrieves the password for an account for the given account name or email address.
		/// </summary>
		/// <param name="account">A string parameter that represents an account name or an email address.</param>
		private void GetPassword(string account, out string emailAddress, out string username, out string password)
		{
			//logger.Debug("Attempting to get password details for account " + account + ".");
			
			emailAddress = null;
			username = null;
			password = null;

			if(account == null || account.Trim().Length == 0)
			{
				return;
			}

			//SqlConnection authenticationDb = new SqlConnection(m_databaseConnectionString);
			//object conn = StorageLayer.GetConnection(m_storageType, m_databaseConnectionString);

			string select = null;
			if(m_storageType == StorageTypes.MSSQL)
			{
				select = "select emailaddress, username, password from Customers cu join CustomerEmailAddresses ce " +
					" on cu.customerid = ce.customerid " +
					"where emailaddress = '" + account + "' or username='" + account + "'";
			}
			else if(m_storageType == StorageTypes.Postgresql)
			{
				select = "select emailaddress, username, password from Customers cu join CustomerEmailAddresses ce " +
					" on cu.customerid = ce.customerid " +
					"where emailaddress ~* '^" + account + "$' or upper(username) = '" + account.ToUpper() + "'";}
			else
			{
				throw new ApplicationException("This storage type is not supported in GetPassword.");
			}
			
			//logger.Debug("Get user details select = " + select);

			try
			{
				DataSet detailsDs = m_storageLayer.GetDataSet(select);

				if(detailsDs.Tables[0].Rows.Count > 0)
				{
					DataRow detailsRow = detailsDs.Tables[0].Rows[0];

					emailAddress = detailsRow["emailaddress"] as string;
					username = detailsRow["username"] as string;
					password = detailsRow["password"] as string;
				}
			}
			catch(Exception excp)
			{
				logger.Warn("Exception ForgottenPasswordController GetPassword: " + excp.Message);
				throw excp;
			}
		}
	}
}
